package com.bookseek.xreader.utils;

import android.os.Handler;
import android.os.Looper;

import com.bookseek.xreader.params.ExtraParams;
import com.bookseek.xreader.params.GujiSearchParams;
import com.bookseek.xreader.params.TkParams;
import com.bookseek.xreader.vo.HttpRetVo;
import com.google.gson.Gson;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class OkHttpUtils {
    //public static String GUJI_SERVER = "https://funseek.deno.dev";
    public static String GUJI_SERVER = "https://bookseek.top";

    // 线程池：核心线程数3，最大线程数5，空闲线程存活时间30秒
    private static final ThreadPoolExecutor THREAD_POOL = new ThreadPoolExecutor(
            3, 5, 30, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>()
    );
    private Handler mainHandler; // 用于切换到主线程回调
    private ConcurrentHashMap<String, Call> downloadCalls; // 存储下载任务，用于取消

    public static Gson gson = new Gson();
    public static String gujiApi(String api){
        return GUJI_SERVER + api;
    }
    public static String gujiW(GujiSearchParams searchParams){
        TkParams params = new TkParams();
        params.p = gson.toJson(searchParams);
        String paramStr = gson.toJson(params);
        return MiniDataUtils.aesEncryptCBCWithIvToBase64SafeUrlStr(paramStr);
    }
    private static OkHttpUtils instance;
    private OkHttpClient client;

    private OkHttpUtils() {
        client = nxOkHttpClient();
        mainHandler = new Handler(Looper.getMainLooper());
        downloadCalls = new ConcurrentHashMap<>();
    }

    public Handler getMainHandler(){
        return mainHandler;
    }
    public  ThreadPoolExecutor getThreadPool(){
        return THREAD_POOL;
    }


    private OkHttpClient gxOkHttpClient(){
        return new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .build();
    }
    private OkHttpClient nxOkHttpClient(){
        try {
            // 创建信任所有证书的 TrustManager
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            // 不验证客户端证书
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            // 不验证服务器证书
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }
                    }
            };

            // 安装信任所有证书的 TrustManager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new SecureRandom());

            // 创建不验证主机名的 SSLSocketFactory
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    // 不验证主机名
                    return true;
                }
            });

            // 设置超时时间
            builder.connectTimeout(15, TimeUnit.SECONDS);
            builder.readTimeout(15, TimeUnit.SECONDS);
            builder.writeTimeout(15, TimeUnit.SECONDS);

            return builder.build();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static OkHttpUtils getInstance() {
        if (instance == null) {
            synchronized (OkHttpUtils.class) {
                if (instance == null) {
                    instance = new OkHttpUtils();
                }
            }
        }
        return instance;
    }

    public void get(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    public void post(String url, String key, String value, Callback callback) {
        RequestBody formBody = new FormBody.Builder()
                .add(key, value)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    // 回调接口
    public interface SqlCallback<T> {
        void onSuccess(T result);
        void onError(Exception e);
    }

    public static abstract class SimpleCallback implements Callback {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public abstract void onResponse(Call call, Response response) throws IOException;
    }

    /**
     * 取消单个文件下载
     * @param fileUrl 要取消的文件URL
     */
    public void cancelDownload(String fileUrl) {
        Call call = downloadCalls.get(fileUrl);
        if (call != null && !call.isCanceled()) {
            call.cancel();
            downloadCalls.remove(fileUrl);
        }
    }

    /**
     * 取消所有下载任务
     */
    public void cancelAllDownloads() {
        for (Call call : downloadCalls.values()) {
            if (!call.isCanceled()) {
                call.cancel();
            }
        }
        downloadCalls.clear();
    }




    /**
     * 添加单个文件下载任务
     * @param fileUrl 下载链接
     * @param writeOs 数据保存
     * @param callback 下载回调
     */
    public void addSingleTask(String fileUrl, ByteArrayOutputStream writeOs, DownloadCallback callback,ExtraParams extra) {
        // 避免重复下载同一URL
        if (downloadCalls.containsKey(fileUrl)) {
            mainHandler.post(() -> callback.onFailure(fileUrl, "正在下载中。。",extra));
            return;
        }
        // 提交下载任务到线程池
        THREAD_POOL.execute(() -> startDownload(fileUrl, writeOs, callback,extra));
    }


    public HttpRetVo getSyncStr(String api){
        DLog.info("api=>>>",api);
        HttpRetVo retVo = new HttpRetVo();
        Request request = new Request.Builder()
                .url(api)
                .addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0")
                .build();
        Call call = client.newCall(request);
        Response response = null;
        try {
            response = call.execute();
            retVo.statusCode = response.code();
            DLog.info("api=",api,"请求 响应码",response.code());
            retVo.success = response.isSuccessful();
            if(retVo.success){
                String text =  response.body()  != null ? response.body().string() : "";
                retVo.text = MiniDataUtils.aesDecryptCBCWithIvFromBase64SafeUrlJSONP(text);
            }
        } catch (IOException e) {
            e.printStackTrace();
            retVo.statusCode = 500;
            retVo.msg = e.getMessage();
        }
        return retVo;

    }
    public HttpRetVo downGetExecute(String fileUrl){
        HttpRetVo retVo = new HttpRetVo();
        ByteArrayOutputStream writeOs = new ByteArrayOutputStream();
        Request request = new Request.Builder()
                .url(fileUrl)
                .build();
        Call call = client.newCall(request);
        Long startTm = System.currentTimeMillis();
        DLog.info("Start Down fileUrl=",fileUrl);
        try {
            Response response = call.execute();
            retVo.statusCode = response.code();
            DLog.info("api=",fileUrl,"请求 响应码",response.code());
            retVo.success = response.isSuccessful();
            if(response.isSuccessful()){
                InputStream inputStream = null;
                try {
                    inputStream = response.body().byteStream();
                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    long totalRead = 0;
                    long totalSize = response.body().contentLength();
                    retVo.length = totalSize;
                    // 写入文件并回调进度
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        //将下载结果保存到writeOs
                        writeOs.write(buffer, 0, bytesRead);
                    }
                    retVo.datas = writeOs.toByteArray();
                } catch (IOException e) {
                    retVo.statusCode = 500;
                    retVo.msg = e.getMessage();
                    DLog.error(fileUrl,"读取数据异常 error=",e.getMessage());
                } finally {
                    // 关闭资源
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    response.body().close();
                }
            }
        } catch (IOException e) {
            retVo.statusCode = 500;
            retVo.msg = e.getMessage();
            e.printStackTrace();
        }
        Long endTm = System.currentTimeMillis();
        DLog.info("Start Down fileUrl=",fileUrl," 下载完毕，耗时=",endTm-startTm," ms"," msg=",retVo.msg);
        return retVo;
    }


    public void downGetEnqueue(String fileUrl,ByteArrayOutputStream writeOs,DownloadCallback callback,ExtraParams extra){
        Request request = new Request.Builder()
                .url(fileUrl)
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                DLog.error("api=",fileUrl,"下载失败",e.getMessage());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) {
                    callback.onFailure(fileUrl, "响应码：" + response.code(),extra);
                    DLog.error("api=",fileUrl,"下载失败 响应码",response.code());
                    return;
                }
                InputStream inputStream = null;
                try {
                    inputStream = response.body().byteStream();
                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    long totalRead = 0;
                    long totalSize = response.body().contentLength();
                    extra.length = totalSize;
                    // 写入文件并回调进度
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        //将下载结果保存到writeOs
                        writeOs.write(buffer, 0, bytesRead);
                    }
                    callback.onSuccess(fileUrl, writeOs,extra);

                } catch (IOException e) {
                    callback.onFailure(fileUrl, e.getMessage(),extra);
                    DLog.error(fileUrl,"读取数据异常 error=",e.getMessage());
                } finally {
                    // 关闭资源
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    response.body().close();
                }
            }
        });
    }
    /**
     * 开始单个文件下载
     */
    private void startDownload(String fileUrl, ByteArrayOutputStream writeOs, DownloadCallback callback,ExtraParams extra) {
        // 通知开始下载（主线程）
        mainHandler.post(() -> callback.onStart(fileUrl,extra));

        Request request = new Request.Builder()
                .url(fileUrl)
                .build();

        Call call = client.newCall(request);
        downloadCalls.put(fileUrl, call); // 保存任务引用

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                DLog.error("api=",fileUrl,"下载失败",e.getMessage());
                // 移除任务引用
                downloadCalls.remove(fileUrl);
                // 回调失败（主线程）
                mainHandler.post(() -> callback.onFailure(fileUrl, e.getMessage(),extra));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) {
                    DLog.error("api=",fileUrl,"下载失败 响应码",response.code());
                    downloadCalls.remove(fileUrl);
                    mainHandler.post(() -> callback.onFailure(fileUrl, "响应码：" + response.code(),extra));
                    return;
                }

                InputStream inputStream = null;

                try {
                    inputStream = response.body().byteStream();

                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    long totalRead = 0;
                    long totalSize = response.body().contentLength();

                    // 写入文件并回调进度
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        writeOs.write(buffer, 0, bytesRead);
                        totalRead += bytesRead;
                        if (totalSize > 0) {
                            int progress = (int) (totalRead * 100 / totalSize);
                            // 回调进度（主线程）
                            if(extra != null && extra.showProgress){
                                mainHandler.post(() -> callback.onProgress(fileUrl, progress,extra));
                            }
                        }
                    }
                    //writeOs.flush();

                    // 下载成功
                    downloadCalls.remove(fileUrl);
                    mainHandler.post(() -> callback.onSuccess(fileUrl, writeOs,extra));

                } catch (IOException e) {
                    DLog.error(fileUrl,"读取数据异常 error=",e.getMessage());
                    downloadCalls.remove(fileUrl);
                    mainHandler.post(() -> callback.onFailure(fileUrl, e.getMessage(),extra));
                } finally {
                    // 关闭资源
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    response.body().close();
                }
            }
        });
    }


    /**
     * 下载回调接口
     */
    public interface DownloadCallback {
        void onStart(String fileUrl, ExtraParams extra); // 开始下载
        void onProgress(String fileUrl, int progress,ExtraParams extra); // 下载进度（0-100）
        void onSuccess(String fileUrl,ByteArrayOutputStream writeOs,ExtraParams extra); // 下载成功
        void onFailure(String fileUrl, String errorMsg,ExtraParams extra); // 下载失败
    }
}    